using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
using System.Web;

namespace NDomain.ExampleModels.BloggingSystem.Infrastructure
{
    public static class ReflectionHelper
    {
        private const BindingFlags fieldFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;

        public static void SetField(object obj, string fieldName, Object value)
        {
            GetField(obj, fieldName).SetValue(obj, value);
        }

        public static FieldInfo GetField(object obj, string fieldName)
        {
            foreach(Type type in GetTypeHierarchy(obj))
            {
                FieldInfo field = type.GetField(fieldName, fieldFlags);
                if (field != null)
                    return field;
            }
            return null;
        }

        public static IEnumerable<Type> GetTypeHierarchy(object obj)
        {
            for (Type type = obj.GetType(); type.BaseType != null; type = type.BaseType)
                yield return type;
        }

        public static ICollection<FieldInfo> GetFields(object o)
        {
            List<FieldInfo> fields = new List<FieldInfo>();

            foreach (Type type in GetTypeHierarchy(o))
                fields.AddRange(type.GetFields(fieldFlags));

            return fields;
        }
    }
}
